package com.liangwj.springbootquickstart.jdk8.lambda;


import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;

/**
 * <b>Description:</b> 方法引用 <br/>
 * @author Lingwenjun
 * @date 2019/1/9-14:05
 * @version 1.0
 */
public class LambdaMethodReference {
    /**
     * 有些时候，lambda表达式的代码就只是一个简单的方法调用而已，遇到这种情况，lambda表达式还可以进一步简化为方法引用。
     * ：：操作符将方法名和对象或类的名字分隔开来。
     * 变量作用域
     * 在Java8之前， 内部类只能访问final的局部变量 ，为了适应lambda表达式，Java8放宽了这种限制，只要变量实际上不可变（effectively final）就可以。
     * 在lambda表达式中，被引用的变量的值不能被修改。做出这个约束的是有原因的，因为lambda表达式中的变量不是线程安全的。
     */
    private final static String[] ARR = {"lianggzone", "spring", "summer"};
    /**
     * 对象::实例对象
     */
    //在java8之前,我们打印list的内容,是这样做的
    public static void print1() {
        List<String> wordList = Arrays.asList(ARR);
        wordList.forEach(new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println("s = " + s);
            }
        });
    }

    //因为Consumer是函数式接口, 可以通过lambda表达式改造下:
    public static void print2() {
         List<String> wordList = Arrays.asList(ARR);
         wordList.forEach(s -> System.out.println("s = " + s));
    }

    //
    public static void print3() {
        List<String> wordList = Arrays.asList(ARR);
        wordList.forEach(System.out::println);
    }

    /**
     * 类::实例对象
     */
    //不区分大小写,对字符串进行排序
    public static String[] sort1() {
        String[] words = new String[]{"a", "c", "f", "j", "b"};
        Arrays.sort(words, (x, y) -> x.compareToIgnoreCase(y));
        return words;
    }

    //改造成方法引用, 表达式 String::compareToIgnoreCase等价于(x, y) -> x.compareToIgnoreCase(y),第一参数会成为执行方法的对象
    public static String[] sort2() {
        String[] words = new String[]{"a", "c", "f", "j", "b"};
        Arrays.sort(words, String::compareToIgnoreCase);
        return words;
    }

    /**
     * 对象::静态方法
     */
    //对集合进行排序
    public static List<Integer> sortList1() {
        List<Integer> integerList = Arrays.asList(2,18,34,53,12,43);
        integerList.sort((i1, i2) -> Integer.compare(i1, i2));
        return integerList;
    }
    //改造成方法引用, 表达式 Integer::compare等价于(i1, i2) -> Integer.compare(i1, i2),第一参数会成为执行方法的对象
    public static List<Integer> sortList2() {
        List<Integer> integerList = Arrays.asList(2,18,34,53,12,43);
        integerList.sort(Integer::compare);
        //integerList.sort(Comparator.comparingInt(Integer::intValue));
        return integerList;
    }

    /**
     * 构造器引用
     */
    //lambda
    public static List<Integer> sortListConstructor() {
        List<Integer> integerList = Arrays.asList(2,18,34,53,12,43);
        integerList.sort(Integer::compare);
        //integerList.sort(Comparator.comparingInt(Integer::intValue));
        // lambda
        integerList.stream().map(word -> {
            return new StringBuilder(word);
        });
        // constructor reference
        integerList.stream().map(StringBuilder::new);
        return integerList;
    }


    public static void main(String[] args) {
        //LambdaMethodReference.print1();
        //LambdaMethodReference.print2();
        //LambdaMethodReference.print3();
        //System.out.println(Arrays.toString(LambdaMethodReference.sort1()));
        //System.out.println(Arrays.toString(LambdaMethodReference.sort2()));
        LambdaMethodReference.sortList1().forEach(System.out::println);
        LambdaMethodReference.sortList2().forEach(System.out::println);
    }
}
